using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AIMovement : MonoBehaviour
{
    #region Class Variables
    [Header("Movement")]
    private float moveSpeed;
    [SerializeField] private float walkSpeed;
    [SerializeField] private float sprintSpeed;
    [SerializeField] private float groundDrag;
    [SerializeField] private PlayerState playerState;
    [SerializeField] private Rigidbody rb;
    [SerializeField] private float movingThreshold = 0.01f;

    [Header("Ground Check")]
    [SerializeField] private float playerHeight;
    [SerializeField] private LayerMask groundMask;
    [HideInInspector] public bool isGrounded;

    [SerializeField] private Transform orientation;
    [SerializeField] private Transform target;

    [HideInInspector] public Vector3 moveDirection;
    #endregion
    #region Startup
    private void Start()
    {
        rb.freezeRotation = true;
    }
    #endregion
    #region Update Logic
    private void Update()
    {
        GroundCheck();
        GetTargetDir();
        UpdateMovementState();
        UpdateDrag();
    }

    private void FixedUpdate()
    {
        MovePlayer();
        SpeedClamp();
    }

    private void UpdateMovementState()
    {
        bool isMovementInput = rb.velocity != Vector3.zero;
        bool isMovingLaterally = IsMovingLaterally();

        PlayerMovementState lateralState = isMovingLaterally || isMovementInput ? PlayerMovementState.Running : PlayerMovementState.Idling;
        playerState.SetPlayerMovementState(lateralState);

        moveSpeed = walkSpeed;

        /*if (isGrounded && Input.GetKey(sprintKey))
        {
            playerState.SetPlayerMovementState(PlayerMovementState.Sprinting);
            moveSpeed = sprintSpeed;
        }*/

        if (!isGrounded)
        {
            playerState.SetPlayerMovementState(PlayerMovementState.Falling);
        }
    }

    private void GetTargetDir()
    {
        moveDirection = (target.position - transform.position).normalized;
        moveDirection.y = 0;
    }

    private void MovePlayer()
    {
        if (isGrounded)
        {
            rb.AddForce(moveDirection.normalized * moveSpeed * 10f, ForceMode.Force);

            if (rb.velocity.y < 0f)
            {
                rb.velocity.Set(rb.velocity.x, 0, rb.velocity.z);
            }
        }
    }

    private void SpeedClamp()
    {
        if (isGrounded)
        {
            Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);

            if (flatVel.magnitude > moveSpeed)
            {
                Vector3 limitedVel = flatVel.normalized * moveSpeed;
                rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
            }
        }
    }

    private void GroundCheck()
    {
        isGrounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.05f, groundMask);
    }

    private void UpdateDrag()
    {
        if (isGrounded)
        {
            rb.drag = groundDrag;
        }
        else
        {
            rb.drag = 0;
        }
    }
    #endregion
    #region State Checks
    private bool IsMovingLaterally()
    {
        Vector3 lateralVelocity = new Vector3(rb.velocity.x, 0f, rb.velocity.y);

        return lateralVelocity.magnitude > movingThreshold;
    }
    #endregion
}
